import axios, { AxiosInstance, AxiosResponse, AxiosHeaders, AxiosError, InternalAxiosRequestConfig } from 'axios';
import { ElMessage } from 'element-plus';
import { getToken } from '../utils';
import router from '../router';

// 定义接口
interface ErrorResponseData {
    code?: number;
    message?: string;
    path?: string;
}

const baseUrl = process.env.BASE_URL || '';

// 移除空值
function removeEmptyValues(obj: any): any {
    return Object.fromEntries(
        Object.entries(obj).filter(([_, v]) => v !== null && v !== undefined && v !== '')
    );
}

/** 创建 Axios 实例 */
class HttpRequest {
    private instance: AxiosInstance;

    constructor() {
        this.instance = axios.create({
            baseURL: baseUrl,
            timeout: 30000
        });

        this.initializeInterceptors();
    }

    /** 初始化拦截器 */
    private initializeInterceptors() {
        this.instance.interceptors.request.use(this.handleRequest, this.handleError);
        this.instance.interceptors.response.use(this.handleResponse, this.handleResponseError);
    }

    /** 请求拦截器处理函数 */
    private handleRequest(config: InternalAxiosRequestConfig): InternalAxiosRequestConfig {
        // 移除空值
        if (config.method === 'post' || config.method === 'put') {
            config.data = removeEmptyValues(config.data);
        }

        // 设置请求头
        if (!config.headers) {
            config.headers = new AxiosHeaders();
        }

        // 处理 GET 请求
        if (config.method === 'get') {
            config.params = { ...config.params };
        } else if (config.method === 'post' || config.method === 'put') {
            if (!(config.headers as AxiosHeaders).get('Content-Type')) {
                config.headers.set("Content-Type", "application/json");
                config.data = JSON.stringify(config.data);  // 确保数据被 JSON.stringify 处理
            }
        }

        // 设置额外的请求头
        (config.headers as AxiosHeaders).set("X-API-Key", `4e7kGzY6w9kQpFvL3uXbRzTp8aN5mJw2`);
        const token = getToken();
        if (token) {
            (config.headers as AxiosHeaders).set('Authorization', `Bearer: ${token}`);
        }
        // 文件上传处理
        if (config.data instanceof FormData) {
            (config.headers as AxiosHeaders).set('Content-Type', 'multipart/form-data');
        }

        return config;
    }

    /** 响应拦截器处理函数 */
    private handleResponse(response: AxiosResponse) {
        if (!response.data) {
            return response;
        }
        if (response.data.code === 200) {
            // ElMessage.success(response.data.message);
            return response.data;
        } else {
            // ElMessage.error(response.data.message);
            return Promise.reject(response.data);
        }
    }
    /** 请求错误处理函数 */
    private handleError(error: AxiosError) {
        if (error.response) {
            const responseData = error.response.data as ErrorResponseData;
            switch (error.response.status) {
                case 401:
                    sessionStorage.removeItem('token');
                    router.push('/login');
                    return;
                default:
                    ElMessage.error(responseData.message);
                    break;
            }
        }
        return Promise.reject(error);
    }
    /** 响应错误处理函数 */
    private handleResponseError(error: AxiosError) {
        if (error.response) {
            // const responseData = error.response.data as ErrorResponseData;
            switch (error.response.status) {
                case 401:
                    sessionStorage.removeItem('token');
                    router.push('/login');
                    break;
                case 403:
                    // message = responseData.path || 'No path provided';
                    break;
                default:
                    // message = 'An error occurred';
                    break;
            }
        }
        return Promise.reject(error);
    }

    /** GET 请求方法 */
    public get<T>(url: string, params?: object): Promise<T> {
        return this.instance.get(url, { params });
    }

    /** POST 请求方法 */
    public post<T>(url: string, data?: object): Promise<T> {
        return this.instance.post(url, data);
    }

    /** 上传文件方法 */
    public upload<T>(url: string, file: FormData): Promise<T> {
        return this.instance.post(url, file, {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        });
    }
}

export default new HttpRequest();
